/**
 * freefuncs.h
 * Some free functions to be used anywhere in the code.
 * These functions do not belong to any specific class.
 *  Created on: Feb 26, 2011
 *      Author: Mo
 */
#pragma once
#include "cmconstants.h"
#include "bitmap.h"
#include <iostream>
#include <fstream>
#include <assert.h>
#include <string.h>
#ifdef GCC
#include <inttypes.h>
#endif
using namespace std;

/**
 * This free function inputs an integer 2D array and its corresponding sizes. Each element of
 * the array is either 0 or 1. The function calculates the length or the borders between
 * the 1 clusters and 0 clusters.
 * \param matrix The input 2D array. The elements of this array should be either 0 or 1.
 * \param rowNum The number of rows in the input matrix.
 * \param colNum The number of columns in the input matrix.
 * \return The sum of the border lengths for all clusters of 1 in a background of 0.
 */
int countBorders (int** matrix, int rowNum, int colNum);

/** Counts the number of non-zero elements in an integer 2D array.
 * \param matrix the integer 2D matrix whose non-zero elements should be counted.
 * \param rowNum,colNum the dimensions of the matrix.
 */
int countNonZeros (int** matrix, int rowNum, int colNum);

/** Calculates a^b, in which both a and b are either zero or positive integers.*/
int intPosPow (int a, int b);

unsigned __int64 twoToThePowerOf (int power); 

/** Sorts a given linear array from high to low.
 * \param intArray The array to be sorted. It will be overwritten.
 * \param size of the linear array
 */
template <typename Type>
void insertionSort (Type intArray[], int size)
{
	int i, j;
	Type current;	
	for (i=1; i != size; i++)
    {
		current = intArray[i];
		j = i; // index of the end of sorted region
		while ((j > 0) && (intArray[j-1] < current))
		{
			intArray[j] = intArray[j-1];
			j = j - 1;
		}
		intArray[j] = current;
	}
}

/** Reads a text file that represents a black and white image and saves it in a .bmp image file.
 * the values of the source file should be either 0 or 1, and the target .bmp file should already 
 * exist with the same dimensions. 
 * This function can be used to visualize the layers of the EightLayerIM objects.
 */
void txt2bmp_bw (string sourceName, string targetName);

/** read a text file that is storing an integer-valued matrix. Creates a mono-color 8-bit bitmap image 
 * out of it by replacing each integer by a pixel with the same intensity. The "color" input tells which component of the pixel's color 
 * 
 */
void txt2bmp (string sourceName, string targetName, string color = "gray");

/** Sets all the pixels of the image whose name is given to black.*/
void setImageToBlack (string imageFileName);

/** Sets all the pixels of the image whose name is given to white.*/
void setImageToWhite (string imageFileName);

/** Creates a text file composed of numbers, where each number represents the intensity of the 
 *  pixel in the same row and column in the grayscale input image.
 */
void bmp2txt (string sourceName, string targetName, string component = "average");

void bmp2txt_rgb (string sourceName, string targetName);

  /** (copied from void bitmap.separateBits (string targetName, string type = "bmp", int layers = 8))
	* This function divides the image into 'layers' number of images, where each image is only black and white (mono color)
	* and keeps the value of the bit in the 'layers' position. For example, ("myfile", "bmp", 2) creates 2 images myfile0.bmp
	* and myfile1.bmp, where each pixel in myfile0.bmp shows the most significant bit of the corresponding pixel in myfile.bmp
	* and each pixel in myfile1.bmp shows the next significant bit of the corresponding pixel in myfile.bmp.
	*/
void separateImageBits (string sourceName, string type = "bmp", int layers = 8);

string int2Str (int number);

int str2Int (string str);

void fillInRandomPermutationArray(int* permArray, int arraySize);

/**converts num to a binary array of the given size: binary(5,4) -> 0101*/
bool binary(int num, int arraySize, bool* buffer); 

/** Like binary() but can work with array-size up to 63. */
bool longBinary(unsigned __int64 num, int arraySize, bool* buffer) ;